home *** CD-ROM | disk | FTP | other *** search
/ Turnbull China Bikeride / Turnbull China Bikeride - Disc 2.iso / STUTTGART / UTIL / MEMORY / OLD / MEM208SRC / !Memphis / c / memcore < prev    next >
Text File  |  1993-09-08  |  21KB  |  823 lines

  1. /*
  2.  * memcore.c
  3.  * Part of the !Memphis distribution
  4.  * (c) bdb/nas, 1991-3
  5.  */
  6.  
  7. /* compile with -dPUFFS for alternate */
  8. /* #define DEBUG */
  9. #include "FS.h"
  10. /*  debug support*/
  11. #ifdef DEBUG
  12. #define DEBUGf printf
  13. #else
  14. #define DEBUGf 1?(void)0:(void)printf
  15. #endif
  16.  
  17.  
  18.  
  19. #ifndef PUFFS
  20. #define MEMFS
  21. #endif
  22.  
  23. #ifdef MEMFS
  24. #define FSNUM 91  /* Acorn-allocated */
  25. #else
  26. #define FSNUM 0xF0
  27. #endif
  28.  
  29. #define FSERR ( (0x100+FSNUM)<<8 )
  30.  
  31. static DEFERR( mb_Lostinode,           FSERR+0xAC,  "inode lost" );
  32. static DEFERR( mb_malloc_failed,       FSERR,       "Not enough free memory" );
  33. static DEFERR( mb_Locked,              FSERR+0xC3,  "Locked" );
  34. static DEFERR( mb_DirNotEmpty,         FSERR+0xB4,  "Directory Not Empty" );
  35. static DEFERR( mb_ObjectInUse,         FSERR+8,     "Object in use" );
  36. static DEFERR( mb_LongName,            FSERR+0xCC,  "FileName too long" );
  37. static DEFERR( mb_NotADir,             FSERR+0xC5,  "Not a Directory" );
  38. static DEFERR( mb_NotAFile,            FSERR+0xC5,  "Not a File" );
  39. static DEFERR( mb_AlreadyExists,       FSERR+0xC4,  "Already exists" );
  40. static DEFERR( mb_BadRename,           FSERR+0x9F,  "Not same disc" );
  41. static DEFERR( mb_enddir,              FSERR,       "Read off end of directory" );
  42. #ifdef MEMFS
  43. char FilingSystemName[]="Mem";
  44. char ModuleName[]="MemFS";
  45. int FilingSystemInformationWord=0x8B800000 + FSNUM;
  46. #else
  47. char FilingSystemName[]="Puf";
  48. char ModuleName[]="PUFFS";
  49. int FilingSystemInformationWord=0x8B800000 + FSNUM;
  50. #endif
  51.  
  52. #define FILENAMELEN 30
  53.  
  54. #ifdef DEBUG
  55. #define DEBUGF printf
  56. #else
  57. #define DEBUGF 1?(void)0:(void)printf
  58. #endif
  59.  
  60. #include "store.h"
  61. #include "inode.h"
  62.  
  63. /*  Event stuff */
  64. #include "ticker.h"
  65.  
  66. int tickerperiod = 100 ; /* centiseconds */
  67.  
  68. int enableticking = 1;
  69.  
  70. void ticker(void)
  71. { Inode_Ticker();
  72. }
  73.  
  74. /*  Directory module */
  75. /*
  76.  *
  77.  * Directory structure:
  78.  *
  79.  * Directory pointer is a char *
  80.  * Each entry has a 4 byte inode, followed by a name, NUL-terminated.
  81.  */
  82. #define DINODE( x ) ( *( int * )x->pos )
  83. #define DNAME( x ) ( (x->pos)+4 )
  84. #define DLEN( x ) (~3&8+x)
  85. #define DMORE( x ) (x->pos)
  86.  
  87. #define DIRPAGESIZE 512         /* directories come in pages of this size */
  88. #define DIRPAGEMARK -3          /* DINODE set to this for no more on this page */
  89.  
  90. typedef struct DIR
  91. { char buf[DIRPAGESIZE];
  92.   char *pos;            /* pointer into dirbuf for current elt */
  93.   int off;              /* offset of current page in directory */
  94.   int len;              /* total length of directory */
  95.   INODE *inode;
  96. } DIR;
  97.  
  98. static DIR *dir_open(INODE *h)
  99. { DIR *p;
  100.   p = malloc(sizeof(DIR));
  101.   if (!p)
  102.     return NULL;
  103.   DEBUGf("dir_open(%d)=%p\n",h->inode,p);
  104.   p->inode = Inode_Dup(h);
  105.   p->len = h->d.length;
  106.   p->off = 0;
  107.   if (p->len && !Inode_Read( p->inode, p->off, (p->len-p->off)>DIRPAGESIZE?DIRPAGESIZE:(p->len-p->off), p->buf ))
  108.     p->pos = p->buf;
  109.   else
  110.     p->pos = NULL;
  111.   return p;
  112. }
  113.  
  114. static _kernel_oserror *dir_close(DIR *p)
  115. {
  116.   DEBUGf("dir_close(%p)\n",p);
  117.   if (p)
  118.   { Inode_Lose(p->inode);
  119.     free(p);
  120.   }
  121.   return NULL;
  122. }
  123.  
  124. static _kernel_oserror *dir_next( DIR *p )
  125. { _kernel_oserror *err;
  126.   DEBUGf("dir_next(%p)\n",p);
  127.   if (!p->pos)
  128.     return ERR(mb_enddir);
  129.   p->pos+=DLEN(strlen(DNAME(p)));
  130.   if (p->pos-p->buf>=p->len-p->off)
  131.     p->pos = NULL;
  132.   else if (DINODE(p)==DIRPAGEMARK)
  133.   { p->off+=DIRPAGESIZE;
  134.     err = Inode_Read( p->inode, p->off, (p->len-p->off)>DIRPAGESIZE?DIRPAGESIZE:(p->len-p->off), p->buf );
  135.     if (err)
  136.     { p->pos = NULL;
  137.       return err;
  138.     }
  139.     else
  140.       p->pos = p->buf;
  141.   }
  142.   return NULL;
  143. }
  144.  
  145. static _kernel_oserror *dir_add( DIR *p, int inode, char *name )
  146. { int off,len;
  147.   _kernel_oserror *err;
  148.   DEBUGf("dir_add(%p,%d,%s)\n",p,inode,name);
  149.   off = p->len % DIRPAGESIZE;
  150.   if (p->len-off!=p->off)
  151.   { p->off = p->len-off;
  152.     err = Inode_Read( p->inode, p->off, (p->len-p->off)>DIRPAGESIZE?DIRPAGESIZE:(p->len-p->off), p->buf );
  153.     if (err)
  154.       return err;
  155.   }
  156.   p->pos = &p->buf[off];
  157.   len = DLEN(strlen(name));
  158.   if (off+len>DIRPAGESIZE-4)
  159.   { DINODE(p) = DIRPAGEMARK;
  160.     p->len += DIRPAGESIZE - off + len;
  161.     err = Inode_EnsureSize(p->inode,p->len);
  162.     if (!err)
  163.       err = Inode_Write( p->inode, p->off, (p->len-p->off)>DIRPAGESIZE?DIRPAGESIZE:(p->len-p->off), p->buf );
  164.     if (err)
  165.       return err;
  166.     p->off += DIRPAGESIZE;
  167.     p->pos = p->buf;
  168.   }
  169.   else
  170.   { p->len += len;
  171.     err = Inode_EnsureSize(p->inode,p->len);
  172.     if (err)
  173.       return err;
  174.   }
  175.   DINODE(p)=inode;
  176.   strcpy(DNAME(p),name);
  177.   p->inode->d.length=p->len;
  178.   Inode_Changed(p->inode);
  179.   err = Inode_Write( p->inode, p->off, (p->len-p->off)>DIRPAGESIZE?DIRPAGESIZE:(p->len-p->off), p->buf );
  180.   return err;
  181. }
  182.  
  183. static _kernel_oserror *dir_del( DIR *p )
  184. { int n;
  185.   _kernel_oserror *err;
  186.   if (!p->pos)
  187.     return ERR(mb_enddir);
  188.   n=DLEN(strlen(DNAME(p)));
  189.   DEBUGf("dir_del(%p)\n",p);
  190.   memcpy(p->pos,p->pos+n,&p->buf[DIRPAGESIZE]-p->pos-n);
  191.   if (p->len-p->off<=DIRPAGESIZE)
  192.   { p->len-=n;
  193.     p->inode->d.length=p->len;
  194.     Inode_Changed(p->inode);
  195.   }
  196.   err = Inode_Write( p->inode, p->off, (p->len-p->off)>DIRPAGESIZE?DIRPAGESIZE:(p->len-p->off), p->buf );
  197.   if (err)
  198.     return err;
  199.   if (p->pos==p->buf && DINODE(p)==DIRPAGEMARK) /* dead page */
  200.   { if (p->off+DIRPAGESIZE<p->len) /* not last page */
  201.     { while (p->off+DIRPAGESIZE<p->len)
  202.       { err = Inode_Read( p->inode, p->off+DIRPAGESIZE, (p->len-p->off-DIRPAGESIZE)>DIRPAGESIZE?DIRPAGESIZE:(p->len-p->off-DIRPAGESIZE), p->buf );
  203.         if (!err)
  204.           err =Inode_Write( p->inode, p->off, (p->len-p->off)>DIRPAGESIZE?DIRPAGESIZE:(p->len-p->off), p->buf );
  205.         if (err) return err;
  206.         p->off += DIRPAGESIZE;
  207.       }
  208.       p->len -= DIRPAGESIZE;
  209.     }
  210.     else
  211.     { p->len = p->off;
  212.       if (p->off)
  213.       { p->off-=DIRPAGESIZE;
  214.         err = Inode_Read( p->inode, p->off, (p->len-p->off)>DIRPAGESIZE?DIRPAGESIZE:(p->len-p->off), p->buf );
  215.         if (err) return err;
  216.         p->pos = p->buf;
  217.         while (DINODE(p)!=DIRPAGEMARK)
  218.           p->pos+=DLEN(strlen(DNAME(p)));
  219.         p->len-=DIRPAGESIZE-(p->pos-p->buf);
  220.       }
  221.     }
  222.     err = Inode_EnsureSize(p->inode,p->len);
  223.     if (err) return err;
  224.     p->inode->d.length = p->len;
  225.     Inode_Changed(p->inode);
  226.   }
  227.   return NULL;
  228. }
  229.  
  230. /*  FileEntry module */
  231.  
  232. struct FileEntry
  233. {       INODE   *inode;
  234.         char    name[FILENAMELEN+1];
  235. };
  236.  
  237. static FileEntry *inodeFileEntry( INODE *d, char *name )
  238. {
  239.   FileEntry *fe;
  240.   fe=malloc( sizeof( FileEntry ) );
  241.   DEBUGf("Wrapped %p(%s) as %p context %p mode ??\n",d,name,fe,&fe /*, _kernel_processor_mode() */);
  242.   if ( !fe )
  243.     return NULL;
  244.   fe->inode = d;
  245.   strcpy( fe->name, name );
  246.   return fe;
  247. }
  248.  
  249. void *private_word;
  250.  
  251. _kernel_oserror * Initialise_FileEntrys( void *privw )
  252. {
  253.   _kernel_oserror *err=Inode_Init();
  254.   private_word = privw;
  255.   if (!err)
  256.   { enableticking=1;
  257.     setcallafter(privw);
  258.   }
  259.   return err;
  260. }
  261.  
  262. static INODE *find_root(char *volname)
  263. {
  264.   storeid s = Store_Find(special_field,volname);
  265.   INODE *inode = Inode_Find(s,1);
  266.   return inode;
  267. }
  268.  
  269. _kernel_oserror *FileEntry_FreeSpace( FileEntry *fe, struct freespace *b )
  270. {
  271.   return Store_FreeSpace(fe->inode->store,b);
  272. }
  273.  
  274. void Terminate_FileEntrys( void )
  275. {
  276.   ShutDown_FileEntrys();
  277. }
  278.  
  279. void ShutDown_FileEntrys( void )
  280. {
  281.   killticking(private_word);
  282.   Inode_Finish();
  283. }
  284.  
  285. _kernel_oserror *DoCommand( int cmd_no, int argc, char *argv[] )
  286. {
  287.   _kernel_swi_regs r;
  288.   argc = argc;
  289.   /*
  290.           Switch between the commands
  291.   */
  292.   switch ( cmd_no )
  293.   {
  294.   case 0: /*      *FSname       */
  295.  
  296.           r.r[0] = FSControl_SelectFilingSystem;
  297.           r.r[1] = ( int )FilingSystemName;
  298.           return _kernel_swi( XOS_Bit | OS_FSControl, &r, &r );
  299.   case 1:
  300.           return reportusage( argc>0?argv[1]:"" );
  301.   default:
  302.           return ERR( mb_BadParameters );
  303.   }
  304. }
  305.  
  306. /*
  307.         This is the SWI handler
  308. */
  309. _kernel_oserror *fs_swi
  310.         int swi_number, 
  311.         _kernel_swi_regs *r, 
  312.         void *private_word
  313.  )
  314. {
  315.         _kernel_oserror *err = NULL;
  316.  
  317.         r = r;
  318.         private_word = private_word;
  319.  
  320.         switch ( swi_number )
  321.         {
  322.         default:
  323.                 err = NULL;
  324.                 break;
  325.         }
  326.  
  327.         return err;
  328. }
  329.  
  330. static char *popnode( char *name, char *buf )
  331. {
  332.   char *p;
  333.   int n;
  334.   p=strchr( name, '.' );
  335.   n=p?p-name:strlen( name );
  336.   if ( n>FILENAMELEN )
  337.     return ( char * )-1;
  338.   strncpy( buf, name, n );
  339.   buf[n]=0;
  340.   if ( p )
  341.     ++p;
  342.   return p;
  343. }
  344.  
  345. _kernel_oserror *FileEntry_DirScan( FileEntry *dir, int i, FileDesc *d, char **name )
  346. { INODE *h;
  347.   DIR *x;
  348.   _kernel_oserror *err;
  349.   static char namebuf[FILENAMELEN];
  350.   DEBUGf("FileEntry_DirScan(%s[%d],%d)\n",dir->name,dir->inode->uses,i);
  351.   if ( dir->inode->d.type!=2 )
  352.     return ERR( mb_NotADir );
  353.   for ( x = dir_open(dir->inode); x && DMORE(x); )
  354.   { if ( !i-- )
  355.     { h = Inode_Find( dir->inode->store, DINODE( x ) );
  356.       if (!h)
  357.       { dir_close(x); return ERR(mb_Lostinode); }
  358.       *d = h->d;
  359.       Inode_Lose(h);
  360.       *name = namebuf;
  361.       strcpy(namebuf,DNAME( x ));
  362.       return dir_close(x);
  363.     }
  364.     err = dir_next(x);
  365.     if (err) return err;
  366.   }
  367.   dir_close(x);
  368.   return ERR(mb_FileNotFound);
  369. }
  370.  
  371. _kernel_oserror *FileEntry_Find( FileEntry *fe, char *name, FileDesc *d )
  372. { _kernel_oserror *err;
  373.   FileEntry *ofe;
  374.   DEBUGf("FileEntry_Find(%s[%d],%s)\n",FileEntry_Name(fe),fe?fe->inode->uses:42,name);
  375.   normalise( &fe, &name );
  376.   err = FileEntry_Open( fe, name, OPENIN, &ofe );
  377.   if ( err )
  378.     return err;
  379.   *d = FileEntry_Desc( ofe );
  380.   return FileEntry_Close( ofe );
  381. }
  382.  
  383. static _kernel_oserror *finddirentry( INODE*dir, char *name, WHICH which, INODE **rh, DIR **where );
  384.  
  385. _kernel_oserror *FileEntry_Open(FileEntry *dfe, char *name, WHICH which, FileEntry **rfe )
  386. {
  387.   INODE *rh,*dir;
  388.   char *dname;
  389.   DIR *w;
  390.   _kernel_oserror *err;
  391.   DEBUGf("FileEntry_Open(%s[%d],%s,%d)\n",FileEntry_Name(dfe),dfe?dfe->inode->uses:42,name,which);
  392.   normalise( &dfe, &name );
  393.   if (!dfe)
  394.   { dir=find_root(NULL);
  395.     if (!dir)
  396.       return ERR( mb_FileNotFound );
  397.     dname="$";
  398.   }
  399.   else
  400.   { dir=Inode_Dup(dfe->inode);
  401.     dname=dfe->name;
  402.   }
  403.   if ( !name || !name[0] )
  404.   { *rfe=inodeFileEntry(dir,dname);
  405.     if (!*rfe)
  406.     { Inode_Lose(dir); return ERR(mb_malloc_failed); }
  407.     return NULL;
  408.   }
  409.   err = finddirentry( dir, name, OPENIN, &rh, &w );
  410.   if ( which<OPENIN )
  411.   { if ( err )
  412.     { rh = Inode_New(dir);
  413.       if (!rh)
  414.       { Inode_Lose(dir); return ERR(mb_malloc_failed); }
  415.       if (which==CREATEDIR)
  416.       { rh->d.type = 2;
  417.         StampInfo(&rh->d.info);
  418.         Inode_Changed(rh);
  419.       }
  420.       err = finddirentry( dir, name, which, &rh, &w );
  421.       if (err)
  422.         Inode_Delete(rh);
  423.     }
  424.   }
  425.   Inode_Lose(dir);
  426.   if ( err )
  427.   { *rfe = NULL;
  428.     return err;
  429.   }
  430.   if ( which==CREATE )
  431.   { if ( rh->d.type==2 )
  432.     {
  433.       *rfe=NULL;
  434.       Inode_Lose(rh);
  435.       dir_close(w);
  436.       return ERR(mb_NotAFile);
  437.     }
  438.     else
  439.     { rh->d.length = 0;
  440.       Inode_Changed(rh);
  441.     }
  442.   }
  443.   else if ( which==CREATEDIR )
  444.   { if ( rh->d.type == 2 )
  445.     {
  446.     }
  447.     else
  448.     { *rfe=NULL;
  449.       Inode_Lose(rh);
  450.       dir_close(w);
  451.       return ERR(mb_NotADir);
  452.     }
  453.   }
  454.   *rfe = inodeFileEntry( rh, w?DNAME( w ):"$" );
  455.   dir_close(w);
  456.   if (!*rfe)
  457.   { Inode_Lose(rh); return ERR(mb_malloc_failed); }
  458.   return NULL;
  459. }
  460.  
  461. /* if (create), add entry else find one
  462.  * return position where found in where, or NULL for root
  463.  */
  464.  
  465. static _kernel_oserror *finddirentry( INODE *dir, char *name, WHICH which, INODE **rh, DIR **where ) 
  466. {
  467.   char buf[100];
  468.   INODE *h,*inode;
  469.   DIR *x;
  470.   _kernel_oserror *err;
  471.   DEBUGf("finddirentry(%p[%d],%s,%d)\n",dir,dir?dir->uses:42,name,which);
  472.   if ( !dir )
  473.   { dir=find_root(NULL);
  474.     if (!dir)
  475.       return ERR( mb_FileNotFound );
  476.   }
  477.   else
  478.     dir = Inode_Dup(dir);
  479.   switch( name[0] )
  480.   {
  481.   case '$':
  482.     Inode_Lose(dir);
  483.     if (name[1] && name[1]!='.')
  484.       return ERR( mb_FileNotFound );
  485.     dir=find_root(NULL);
  486.     if (!dir)
  487.       return ERR( mb_FileNotFound );
  488.     if ( !name[1] )
  489.     {
  490. returnroot:
  491.         inode=Inode_Dup(dir);
  492.         x=NULL;
  493.         goto returninode;
  494.     }
  495.     name+=2;
  496.     break;
  497.   case ':':
  498.     name=popnode( name+1, buf );
  499.     Inode_Lose(dir);
  500.     dir=find_root(buf);
  501.     if (!dir)
  502.       return ERR( mb_FileNotFound );
  503.     if ( !name )
  504.       goto returnroot;
  505.     if ( name[0]=='$' )
  506.     { if (!name[1])
  507.         goto returnroot;
  508.       else if (name[1]!='.')
  509.       { Inode_Lose(dir); return ERR( mb_FileNotFound ); }
  510.       name+=2;
  511.     }
  512.     break;
  513.   }
  514. searchinode:
  515.   if ( dir->d.type!=2 )
  516.   { Inode_Lose(dir); return ERR( mb_NotADir ); }
  517.   name = popnode( name, buf );
  518.   if ( name==( char * )-1 )
  519.     { Inode_Lose(dir); return ERR( mb_LongName ); }
  520.   if ( buf[0]=='^' && !buf[1] )
  521.   {
  522.     if (dir->inode==1)
  523.     { inode = Inode_Dup(dir);
  524.       x = NULL;
  525.       goto foundobj;
  526.     }
  527.     inode = Inode_Find( dir->store,dir->parentinode );
  528.     if ( !inode )
  529.       { Inode_Lose(dir); return ERR( mb_Lostinode ); }
  530.     h = Inode_Find( inode->store,inode->parentinode );
  531.     if ( !h )
  532.     { Inode_Lose(inode); Inode_Lose(dir); return ERR( mb_Lostinode ); }
  533.     for ( x = dir_open( h ); x && DMORE(x); )
  534.     { if ( DINODE( x )==inode->inode )
  535.       { Inode_Lose(h);
  536.         goto foundobj;
  537.       }
  538.       err = dir_next(x);
  539.       if (err) return err;
  540.     }
  541.     dir_close(x);
  542.     Inode_Lose(inode);
  543.     Inode_Lose(h);
  544.     Inode_Lose(dir); 
  545.     return ERR( mb_FileNotFound );
  546.   }
  547.   for ( x = dir_open( dir ); x && DMORE(x); )
  548.   { if ( !stricmp( DNAME( x ), buf ) )
  549.       { inode = Inode_Find( dir->store,DINODE(x) );
  550.         if (!inode)
  551.         { dir_close(x); Inode_Lose(dir); return ERR( mb_Lostinode ); }
  552. foundobj:
  553.         if ( name )
  554.         { Inode_Lose(dir);
  555.           dir=inode;
  556.           dir_close(x); 
  557.           goto searchinode;
  558.         }
  559.         if ( which<OPENIN )
  560.         { dir_close(x); Inode_Lose(dir); Inode_Lose(inode); return ERR(mb_AlreadyExists); }
  561.         goto returninode;
  562.       }
  563.     err = dir_next(x);
  564.     if (err) return err;
  565.   }
  566.   if ( which>=OPENIN || name )
  567.   { dir_close(x); Inode_Lose(dir); return ERR( mb_FileNotFound ); }
  568.   inode = *rh;
  569.   err = dir_add( x, inode->inode, buf );
  570.   if (err) return err;
  571.   inode->parentinode = dir->inode;
  572.   Inode_Changed(inode);
  573. returninode:
  574.   Inode_Lose(dir);
  575.   *rh=inode;
  576.   *where=x;
  577.   return NULL;
  578. }
  579.  
  580. _kernel_oserror *FileEntry_Close( FileEntry *fe )
  581. {
  582.   DEBUGf("FileEntry_Close(%s)[%d]\n",FileEntry_Name(fe),fe?fe->inode->uses:42);
  583.   if ( fe )
  584.   { Inode_Lose(fe->inode);
  585.     free( fe );
  586.   }
  587.   return NULL;
  588. }
  589.  
  590. _kernel_oserror *FileEntry_Delete( FileEntry *dir, char *name, FileDesc *d )
  591. {
  592.   INODE *h,*dh;
  593.   DIR *w;
  594.   _kernel_oserror *err;
  595. #ifdef DEBUG
  596.   printf( " Delete dir=%s[%d] name=%s\n", FileEntry_Name(dir),dir?dir->inode->uses:42, name?name:"NULL" );
  597. #endif
  598.   normalise( &dir, &name );
  599.   if ( !name )
  600.     return ERR( mb_ObjectInUse );
  601.   if (!dir)
  602.   { dh=find_root(NULL);
  603.     if (!dh)
  604.       return ERR( mb_FileNotFound );
  605.   }
  606.   else
  607.     dh=Inode_Dup(dir->inode);
  608.   err = finddirentry( dh, name, OPENIN, &h, &w );
  609.   Inode_Lose(dh);
  610.   if ( err )
  611.     return err;
  612. #ifdef DEBUG
  613.   printf( " Delete h=%p\n", h );
  614. #endif
  615.   if ( h->d.attr&Attr_L )
  616.   { Inode_Lose(h); dir_close(w); return ERR( mb_Locked ); }
  617.   if ( h->d.type==2 && h->d.length>0 || !w )
  618.   { Inode_Lose(h); dir_close(w); return ERR( mb_DirNotEmpty ); }
  619.   *d = h->d;
  620.   Inode_Delete(h);
  621.   dir_del(w);
  622.   dir_close(w); 
  623.   return NULL;
  624. }
  625.  
  626. _kernel_oserror *FileEntry_Rename( FileEntry *dir, char *name, FileEntry *newdir, char *newname )
  627. {
  628.   INODE *h;
  629.   DIR *w1,*w2;
  630.   _kernel_oserror *err;
  631.   DEBUGf("FileEntry_Rename(%s[%d],%s,%s[%d],%s)\n",dir->name,dir?dir->inode->uses:42,name,newdir->name,newdir?newdir->inode->uses:42,newname);
  632.   normalise( &dir, &name );
  633.   normalise( &newdir, &newname );
  634.   err = finddirentry( dir?dir->inode:NULL, name, OPENIN, &h, &w1 );
  635.   if ( err )
  636.     return err;
  637.   if ( h->d.attr&Attr_L || !w1 )
  638.   { Inode_Lose(h); dir_close(w1); return ERR( mb_Locked ); }
  639.   err = finddirentry( newdir?newdir->inode:NULL, newname, CREATE, &h, &w2 );
  640.   if ( err )
  641.   { Inode_Lose(h); dir_close(w1); return err; }
  642.   if ( !w2 || w1->inode->store != w2->inode->store )
  643.   { Inode_Lose(h); dir_close(w1); return ERR(mb_BadRename); }
  644.   if (w1->inode==w2->inode)
  645.   { dir_close(w1);
  646.     dir_close(w2);
  647.     Inode_Lose(h);
  648.     err = finddirentry( dir?dir->inode:NULL, name, OPENIN, &h, &w1 );
  649.     if ( err )
  650.       return err;
  651.   }
  652.   else
  653.     dir_close(w2);
  654.   Inode_Lose(h);
  655.   dir_del(w1);
  656.   dir_close(w1);
  657.   return NULL;
  658. }
  659.  
  660. _kernel_oserror *FileEntry_GetBytes( FileEntry *fe, char *p, int o, int n, int *newpos, int *len )
  661. {
  662.   DEBUGf("FileEntry_GetBytes(%s[%d],%p,%d,%d)\n",FileEntry_Name(fe),fe?fe->inode->uses:42,p,o,n);
  663.   *newpos = o+n; *len = n;
  664.   return Inode_Read( fe->inode, o, n, p );
  665. }
  666.  
  667. _kernel_oserror * FileEntry_GetByte( FileEntry *fe, int *b )
  668. {
  669.   fe = fe;
  670.   b = b;
  671.   return ERR(mb_BadParameters);
  672. }
  673.  
  674. _kernel_oserror *FileEntry_PutBytes( FileEntry *fe, char *p, int o, int n, int *newpos )
  675. { _kernel_oserror *err;
  676.   DEBUGf("FileEntry_PutBytes(%s[%d],%p,%d,%d)\n",FileEntry_Name(fe),fe?fe->inode->uses:42,p,o,n);
  677.   *newpos = n+o;
  678.   if ( n+o>fe->inode->d.length )
  679.   { if ( ( err = FileEntry_SetLength( fe, n+o ) )!=NULL )
  680.       return err;
  681.   }
  682.   if ( n )
  683.   { err = Inode_Write( fe->inode, o, n, p );
  684.     o+=n;
  685.     return err;
  686.   }
  687.   return NULL;
  688. }
  689.  
  690. _kernel_oserror *FileEntry_PutByte( FileEntry *fe , int c )
  691. {
  692.   fe = fe;
  693.   c = c;
  694.   return ERR(mb_BadParameters);
  695. }
  696.  
  697. static char zero[512];
  698.  
  699. _kernel_oserror *FileEntry_PutZeros( FileEntry *fe, int o, int n )
  700. { _kernel_oserror *err=NULL;
  701.   DEBUGf("FileEntry_PutZeros(%s[%d],%d,%d)\n",FileEntry_Name(fe),fe?fe->inode->uses:42,o,n);
  702.   if ( n+o>fe->inode->d.length )
  703.   { if ( ( err = FileEntry_SetLength( fe, n+o ) )!=NULL )
  704.       return err;
  705.   }
  706.   while ( n>512 )
  707.   { err=Inode_Write( fe->inode, o, 512, zero );
  708.     o+=512; n-=512;
  709.   }
  710.   if (n)
  711.   { err=Inode_Write( fe->inode, o, n, zero );
  712.     o+=n;
  713.   }
  714.   return NULL;
  715. }
  716.  
  717. _kernel_oserror *FileEntry_EnsureSize( FileEntry *fe, int size )
  718. {
  719.   DEBUGf("FileEntry_EnsureSize(%s[%d],%d)\n",FileEntry_Name(fe),fe?fe->inode->uses:42,size);
  720.   if ( size <= fe->inode->allocated )
  721.     return NULL;
  722.   return Inode_EnsureSize( fe->inode, size );
  723. }
  724.  
  725. _kernel_oserror *FileEntry_SetLength( FileEntry *fe, int length )
  726. { _kernel_oserror *err;
  727.   DEBUGf("FileEntry_SetLength(%s[%d],%d)\n",FileEntry_Name(fe),fe?fe->inode->uses:42,length);
  728.   if ( NULL!=( err=FileEntry_EnsureSize( fe, length ) ) )
  729.     return err;
  730.   fe->inode->d.length = length;
  731.   Inode_Changed( fe->inode );
  732.   return NULL;
  733. }
  734.  
  735. _kernel_oserror *FileEntry_Access( FileEntry *dir, char *name, int attr )
  736. { FileEntry *fe;
  737.   _kernel_oserror *err;
  738.   DEBUGF("Access %s[%d] %s %x\n",FileEntry_Name(dir),dir?dir->inode->uses:42,name?name:"NULL",attr);
  739.   err = FileEntry_Open(dir,name,OPENIN,&fe);
  740.   if (err)
  741.     return err;
  742.   fe->inode->d.attr = attr;
  743.   Inode_Changed( fe->inode );
  744.   FileEntry_Close(fe);
  745.   return NULL;
  746. }
  747.  
  748. _kernel_oserror *FileEntry_SetInfo( FileEntry *fe, Information_Fields info )
  749. {
  750.   DEBUGf("FileEntry_SetInfo(%s)[%d]\n",FileEntry_Name(fe),fe->inode->uses);
  751.   fe->inode->d.info = info;
  752.   Inode_Changed( fe->inode );
  753.   return NULL;
  754. }
  755.  
  756. _kernel_oserror *FileEntry_Flush ( FileEntry *fe )
  757. {
  758.   DEBUGf("FileEntry_Flush(%s)[%d]\n",FileEntry_Name(fe),fe?fe->inode->uses:42);
  759.   return NULL;
  760. }
  761.  
  762. _kernel_oserror *FileEntry_SetSeqPtr( FileEntry *fe , int seqptr )
  763. {
  764.   DEBUGf("FileEntry_SetSeqPtr(%s)[%d] %d\n",FileEntry_Name(fe),fe?fe->inode->uses:42,seqptr);
  765.   return ERR(mb_BadParameters);
  766. }
  767.  
  768. void FileEntry_FileInfoObject
  769.   FileEntry *fse
  770.  )
  771. {
  772.   DEBUGf("FileEntry_FileInfoObject(%s)[%d]\n",FileEntry_Name(fse),fse?fse->inode->uses:42);
  773.   printf( "%-20s %8p %8p %8x %8x %7p %7p %7x %d\n\r", 
  774.            fse->name, 
  775.            fse->inode->d.info.load_exec.load_address, 
  776.            fse->inode->d.info.load_exec.execute_address, 
  777.            fse->inode->d.length, 
  778.            fse->inode->d.attr, 
  779.            fse, 
  780.            fse->inode, 
  781.            fse->inode->allocated, 
  782.            fse->inode->uses );
  783. }
  784.  
  785. char *FileEntry_DiscName( FileEntry *fe )
  786. {
  787.   DEBUGf("FileEntry_DiscName(%s)[%d]\n",FileEntry_Name(fe),fe?fe->inode->uses:42);
  788.   if (!fe)
  789.     return "\"Unset\"";
  790.   return Store_Name(fe->inode->store);
  791. }
  792.  
  793. char *FileEntry_SpecialField( FileEntry *fe )
  794. {
  795.   DEBUGf("FileEntry_SpecialField(%s)[%d]\n",FileEntry_Name(fe),fe?fe->inode->uses:42);
  796.   if (!fe)
  797.     return NULL;
  798.   return Store_SpecialField(fe->inode->store);
  799. }
  800.  
  801. char *FileEntry_Name( FileEntry *fe )
  802. {
  803.   return fe?fe->name:"\"Unset\"";
  804. }
  805.  
  806. FileDesc FileEntry_Desc( FileEntry *fe )
  807. {
  808.   DEBUGf("FileEntry_Desc(%s)[%d]\n",FileEntry_Name(fe),fe?fe->inode->uses:42);
  809.   return fe->inode->d;
  810. }
  811.  
  812. int FileEntry_SeqPtr( FileEntry *fe )
  813. {
  814.   DEBUGf("FileEntry_SeqPtr(%s)[%d]\n",FileEntry_Name(fe),fe?fe->inode->uses:42);
  815.   return -1;
  816. }
  817.  
  818. int FileEntry_Allocated( FileEntry *fe )
  819. { return fe->inode->allocated;
  820. }
  821.